home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 1.iso / connect / _j2 / wvnsc926 / rcs / wvattach.c < prev    next >
C/C++ Source or Header  |  1994-09-21  |  44KB  |  1,763 lines

  1. head     1.9;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.9
  10. date     94.09.16.00.57.09;  author jcooper;  state Exp;
  11. branches ;
  12. next     1.8;
  13.  
  14. 1.8
  15. date     94.08.24.17.59.26;  author jcooper;  state Exp;
  16. branches ;
  17. next     1.7;
  18.  
  19. 1.7
  20. date     94.08.11.00.09.17;  author jcooper;  state Exp;
  21. branches ;
  22. next     1.6;
  23.  
  24. 1.6
  25. date     94.06.09.18.51.30;  author rushing;  state Exp;
  26. branches ;
  27. next     1.5;
  28.  
  29. 1.5
  30. date     94.05.23.18.37.00;  author jcooper;  state Exp;
  31. branches ;
  32. next     1.4;
  33.  
  34. 1.4
  35. date     94.05.19.02.02.10;  author rushing;  state Exp;
  36. branches ;
  37. next     1.3;
  38.  
  39. 1.3
  40. date     94.02.24.21.27.10;  author jcoop;  state Exp;
  41. branches ;
  42. next     1.2;
  43.  
  44. 1.2
  45. date     94.01.22.01.30.03;  author jcoop;  state Exp;
  46. branches ;
  47. next     1.1;
  48.  
  49. 1.1
  50. date     94.01.16.12.10.08;  author jcoop;  state Exp;
  51. branches ;
  52. next     ;
  53.  
  54.  
  55. desc
  56. @jcoop's MIME and attachment routines
  57. @
  58.  
  59.  
  60. 1.9
  61. log
  62. @zero-padding in subject template, cleanup for 92.6
  63. @
  64. text
  65. @/********************************************************************
  66.  *                                                                  *
  67.  *  MODULE    :  WVATTACH.C                                         *
  68.  *                                                                  *
  69.  *  PURPOSE   : This file contains functions for attachments to     *
  70.  *              mail or news posting                                *
  71.  *                                                                  *
  72.  *  ENTRY POINTS: Attach ()                                         *
  73.  *                                                                  *
  74.  * Author: John S. Cooper (jcooper@@netcom.com)                      *
  75.  *   Date: Nov 28, 1993                                             *
  76.  ********************************************************************/
  77. /* 
  78.  * $Id: wvattach.c 1.8 1994/08/24 17:59:26 jcooper Exp $
  79.  * $Log: wvattach.c $
  80.  * Revision 1.8  1994/08/24  17:59:26  jcooper
  81.  * misc encoding/decoding changes
  82.  *
  83.  * Revision 1.7  1994/08/11  00:09:17  jcooper
  84.  * Enhancements to Mime and article encoding/encoding
  85.  *
  86.  * Revision 1.6  1994/06/09  18:51:30  rushing
  87.  * problem with symbol 'header' on AXP/NT
  88.  *
  89.  * Revision 1.5  1994/05/23  18:37:00  jcooper
  90.  * new attach code, session [dis]connect
  91.  *
  92.  * Revision 1.3  1994/02/24  21:27:10  jcoop
  93.  * jcoop changes
  94.  *
  95.  * Revision 1.2  1994/01/22  01:30:03  jcoop
  96.  * 90.2 changes
  97.  *
  98.  * Revision 1.1  1994/01/16  12:10:08  jcoop
  99.  * Initial revision
  100.  *
  101.  */ 
  102. #include <windows.h>
  103. #include <windowsx.h>
  104. #include "wvglob.h"
  105. #include "winvn.h"
  106. #pragma hdrstop
  107. #include <string.h>
  108. #include <ctype.h>        /* for isspace, isalnum, etc */
  109. #include <stdlib.h>        /* for itoa */
  110.  
  111. extern void     UpdateBlockStatus ();    // in wvcoding.c
  112. /*
  113.  * Forward Declarations
  114.  */
  115. void    AppendPlainFileToPost (char *fileName);
  116. BOOL    SplitCurrentHeader (TypTextBlock *header, TypTextBlock *body, TypTextBlock *tail, char *origSubject);
  117. BOOL    AddMIMEVersion (TypTextBlock *header);
  118. BOOL    InitiateAttach (int useWnd, int DocType);
  119. void    EndAttach ();
  120. void    PostTextBlock (TypTextBlock *block);
  121. unsigned long PostPartialTextBlock (TypTextBlock *block, unsigned long start, unsigned long maxBytes);
  122. int     PostOneLine (char *str, unsigned long *byteCount, unsigned long maxBytes);
  123. void    GenerateSubject (TypTextBlock *header, char *origSubject, unsigned int part, unsigned int numParts);
  124. HWND    CreateGlobalPostingWnd (HWND hWnd);
  125. void     FlushCommSpool ();
  126.  
  127. /*
  128.  * Globals 
  129.  */
  130. // NUM_ENCODING_TYPES should be set in wvglob.h to the # items here
  131. char *EncodingTypes[] = { "Base-64", "UU", "XX", "Custom", "None" };
  132.  
  133. // NUM_CONTENT_TYPES should be set in wvglob.h to the # items here
  134. char *ContentTypes[] =  
  135.     {    "Text/Plain",
  136.         "Text/Richtext",
  137.         "Video/MPEG",
  138.         "Video/AVI",
  139.         "Image/JPEG",
  140.         "Image/GIF",
  141.         "Audio/Basic",
  142.         "Application/Zip",
  143.         "Application/PostScript",
  144.         "Other" };
  145.  
  146. #define CURRENT_WND     1
  147. #define NEW_WND        2
  148. #define EDIT_SIZE_INC    512
  149.  
  150. #define ATTACH_NONE              0
  151. #define ATTACH_START             1     // state constants for ProcessAttachment
  152. #define ATTACH_FIRST_IN_THIS_WND 2    
  153. #define ATTACH_FIRST_IN_NEXT_WND 3 
  154. #define ATTACH_WAIT              4
  155. #define ATTACH_MAIN              5
  156. #define ATTACH_DONE              6
  157.  
  158. HWND hThisEditWnd;
  159. HWND hParentWnd;
  160. TypTextBlock *headerBlock, *body, *attachment, *tail;
  161. unsigned int thisPart, numParts;
  162. int AttachmentState;
  163. char attachmentID[MAXINTERNALLINE], origSubject[MAXINTERNALLINE];    
  164. WndEdit *thisPostWnd;
  165. int thisDocType;
  166.  
  167. unsigned int editSize;        // cannot exceed 64k in an edit window
  168. unsigned int editMaxSize;
  169. char *editMem;
  170. int aMode;                // attachment mode for ended line chars
  171. int saveReviewAttach;
  172.  
  173. #define MAX_COMM_SPOOL 1000
  174. unsigned int commSpoolLen;
  175. char *commSpool;
  176.  
  177. /* ---------------------------------------------------------------------------
  178.  * EncodingTypeToNum converts a string describing a coding type into the
  179.  * internal numeric representation
  180.  */
  181. int
  182. EncodingTypeToNum (char *str)
  183. {
  184.     if (!stricmp (str, "Base-64"))
  185.         return CODE_BASE64;
  186.     else if (!stricmp (str, "UU"))
  187.         return CODE_UU;
  188.     else if (!stricmp (str, "XX"))
  189.         return CODE_XX;
  190.     else if (!stricmp (str, "Custom"))
  191.         return CODE_CUSTOM;
  192.     else if (!stricmp (str, "None"))
  193.         return CODE_NONE;
  194.     else
  195.         return CODE_UNKNOWN;
  196. }
  197.  
  198. /* ---------------------------------------------------------------------------
  199.  * hParentWnd is handle to multi-line edit posting window
  200.  *    Called by wvpost.c after file selected and attachment dialog completed
  201.  *    Based on globals set in attachment dialog, creates attachment
  202.  *    possibly encoded, with MIME headers, and posts it
  203.  *    
  204.  *    If ReviewAttach is set, add attachment to post/mail windows (creating
  205.  *    new windows as necessary for message/partial)
  206.  */
  207. void
  208. Attach (WndEdit *WndPost, char *fileName, int DocType)
  209. {
  210.     time_t theTime;
  211.     unsigned long offset, mimeUsage;
  212.             
  213.     hParentWnd = WndPost->hWnd;
  214.     hThisEditWnd = WndPost->hWndEdit;
  215.     WndPost->dirty = DT_DIRTY;
  216.     thisDocType = DocType;
  217.     thisPostWnd = WndPost;    
  218.     // Initialize text blocks
  219.     if ((headerBlock= InitTextBlock (hCodedBlockWnd)) == NULL)
  220.         return;
  221.     if ((body       = InitTextBlock (hCodedBlockWnd)) == NULL)
  222.         return;
  223.     if ((tail       = InitTextBlock (hCodedBlockWnd)) == NULL)
  224.         return;
  225.     if ((attachment = InitTextBlock (hCodedBlockWnd)) == NULL)
  226.         return;
  227.  
  228.     aMode = ADD_TO_EDIT;    // end all lines in \r\n
  229.  
  230.     if (!ReviewAttach)
  231.     {
  232.         if ((commSpool = (char *)GlobalAllocPtr (GMEM_MOVEABLE, MAX_COMM_SPOOL*sizeof (char))) == NULL)
  233.         {
  234.             MessageBox (hParentWnd, "Memory allocation failure", "Comm Spool Init Failed", MB_OK);
  235.             return;
  236.         }            
  237.         commSpool[0] = '\0';
  238.         commSpoolLen = 0;
  239.     }
  240.     
  241.     saveReviewAttach = ReviewAttach;
  242.     if (DocType == DOCTYPE_MAIL)
  243.         ReviewAttach = TRUE;            // must review when mailing
  244.         
  245.     CreateStatusArea (hParentWnd);        // init hCodedBlockWnd and currentCoded
  246.     strcpy (currentCoded->ident, fileName);    // status info
  247.  
  248.     if (EncodingTypeNum == CODE_NONE)
  249.     {        
  250.         if (ReadFileToTextBlock (hParentWnd, attachment, fileName, aMode) == FAIL)
  251.             {  FinishAttachment (ABORT); return;  }
  252.     }
  253.     else     if (Encode (attachment, fileName, aMode) == FAIL)
  254.         {  FinishAttachment (ABORT); return;  }
  255.  
  256.     CodingState = ATTACH_POSTING;
  257.     InvalidateRect (hCodedBlockWnd, NULL, TRUE);    // clear background
  258.  
  259.     time (&theTime);
  260.     sprintf (attachmentID, "\"%ld@@%s\"", theTime, UserName);
  261.         
  262.     if (SplitCurrentHeader (headerBlock, body, tail, origSubject))
  263.         {  FinishAttachment (ABORT); return;  }
  264.     
  265.     if (!GenerateMIME || BlankBeforeMIME)
  266.        if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  267.         {  FinishAttachment (ABORT); return;  }
  268.  
  269.         if (GenerateMIME && AddMIMEVersion (headerBlock))
  270.             {  FinishAttachment (ABORT); return;  }
  271.   
  272.     // if header+tail won't fit in ArticleSplitLength bytes, can't do it
  273.     if (headerBlock->numBytes + tail->numBytes + 200 > ArticleSplitLength)
  274.     {
  275.         MessageBox (hCodedBlockWnd, "Article split length too short to contain headers", "Article Split Length Too Small", MB_OK);
  276.         FinishAttachment (ABORT); return;
  277.     }
  278.  
  279.     // if the attachment won't fit in this article, force start in next
  280.     if (!AttachInNewArt && 
  281.        (body->numBytes + headerBlock->numBytes + tail->numBytes + 200 > ArticleSplitLength))
  282.     {
  283.         MessageBox (hCodedBlockWnd, "Beginning attachment in next article", "Edit Window Space Shortage", MB_OK);
  284.         AttachInNewArt == TRUE;
  285.     }
  286.     
  287.     if (ArticleSplitLength > 0)
  288.     {
  289.         offset = (AttachInNewArt) ? 0 : body->numBytes;
  290.         // calc encodelength/splitlength rounded up
  291.         numParts = (int)((attachment->numBytes + offset + 
  292.              ArticleSplitLength) / ArticleSplitLength);
  293.         // now add in the length of header+sig for each part
  294.         // the extra 200 bytes is rough avg for the MIME headers
  295.         // on each part.  Round up to next articlesplitlen
  296.         mimeUsage = GenerateMIME ? 200L : 0L;
  297.         numParts = (int)((attachment->numBytes + offset + 
  298.              (long)numParts*(headerBlock->numBytes + tail->numBytes + mimeUsage) + 
  299.              ArticleSplitLength) / ArticleSplitLength);
  300.         } else
  301.             numParts = 1;
  302.  
  303.     AttachmentState = ATTACH_START;
  304.     ProcessAttach (CONTINUE);
  305. }
  306.  
  307. /* ---------------------------------------------------------------------------
  308.  * ProcessAttach
  309.  * this is written as a state machine to allow interruption in !ReviewMode
  310.  * to wait for News Server comm responses.
  311.  * Thus in !ReviewMode, after an Initiate/EndAttach, we give up control
  312.  * and wvutil calls ProcessAttach when ready to continue
  313.  */
  314. void
  315. ProcessAttach (int action)
  316. {
  317.     static unsigned long attachLine, byteCount, saveHeaderLines, saveHeaderBytes, dummyLong;
  318.     static BOOL MultipartMixed;
  319.     char temp[MAXINTERNALLINE];
  320.     static int abort;
  321.     int i, found;
  322.         
  323.     if (action == ABORT) 
  324.     {
  325.         MessageBox (hCodedBlockWnd, "Posting with attachment aborted", "Attachment", MB_OK|MB_ICONHAND);
  326.         AttachmentState = ATTACH_DONE;
  327.     }
  328.  
  329.   while (AttachmentState != ATTACH_NONE) {
  330.     switch (AttachmentState) {
  331.  
  332.     case ATTACH_START:
  333.         abort = ABORT;
  334.         byteCount = 0;
  335.         MultipartMixed = FALSE;
  336.         attachLine = 0;
  337.         saveHeaderLines = headerBlock->numLines;
  338.         saveHeaderBytes = headerBlock->numBytes;
  339.         currentCoded->numLines = 0;
  340.         currentCoded->numBytes = 0;
  341.  
  342.         if (AttachInNewArt)
  343.         {
  344.             thisPart = 0;
  345.             AttachmentState = ATTACH_FIRST_IN_NEXT_WND;
  346.         }
  347.         else
  348.         {
  349.             thisPart = 1;
  350.             AttachmentState = ATTACH_FIRST_IN_THIS_WND;
  351.         }
  352.         currentCoded->sequence = thisPart;    // status window info
  353.  
  354.         if (InitiateAttach (CURRENT_WND, thisDocType))
  355.             {  AttachmentState = ATTACH_DONE; break;  }
  356.         if (!ReviewAttach)
  357.             return;
  358.  
  359.         break;
  360.  
  361.     case ATTACH_FIRST_IN_THIS_WND:
  362.         if (!ReviewAttach)
  363.             CommState = ST_POST_WAIT_END;
  364.             
  365.         if (body->numLines != 0)    // if have body, then mixed
  366.         {
  367.           GenerateSubject (headerBlock, origSubject, thisPart, numParts);
  368.           saveHeaderBytes = headerBlock->numBytes;
  369.  
  370.           if (GenerateMIME)
  371.           {
  372.             if (AddEndedLineToTextBlock (headerBlock, "Content-Type: multipart/mixed;",aMode))
  373.               {  AttachmentState = ATTACH_DONE; break;  }
  374.  
  375.             sprintf (temp, "     Boundary=\"%s\"", MIMEBoundary);
  376.             if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  377.             {  AttachmentState = ATTACH_DONE; break;  }
  378.           
  379.             // blank preamble here
  380.             // each boundary must be preceded by a CRLF (add "")
  381.             if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  382.             {  AttachmentState = ATTACH_DONE; break;  }
  383.             sprintf (temp, "--%s", MIMEBoundary);
  384.             if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  385.             {  AttachmentState = ATTACH_DONE; break;  }
  386.                   
  387.                     // explicitly type the encapsulated section
  388.             if (AddEndedLineToTextBlock (headerBlock, "Content-Type: text/plain", aMode))
  389.             {  AttachmentState = ATTACH_DONE; break;  }
  390.             if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  391.             {  AttachmentState = ATTACH_DONE; break;  }
  392.           
  393.             if (AddEndedLineToTextBlock (body, "", aMode))
  394.             {  AttachmentState = ATTACH_DONE; break;  }
  395.             sprintf (temp, "--%s", MIMEBoundary);
  396.             if (AddEndedLineToTextBlock (body, temp, aMode))
  397.             {  AttachmentState = ATTACH_DONE; break;  }
  398.           } 
  399.           else    // no MIME
  400.           {
  401.               if (AddEndedLineToTextBlock (body, "", aMode))
  402.             {  AttachmentState = ATTACH_DONE; break;  }
  403.               if (AddEndedLineToTextBlock (body, "BEGIN --- CUT HERE --- Cut Here --- cut here ---", aMode))
  404.             {  AttachmentState = ATTACH_DONE; break;  }
  405.           }
  406.           PostTextBlock (headerBlock);
  407.           PostTextBlock (body);
  408.           MultipartMixed = TRUE;
  409.           byteCount = headerBlock->numBytes + body->numBytes;
  410.         }
  411.         AttachmentState = ATTACH_MAIN;
  412.         break;
  413.  
  414.     case ATTACH_FIRST_IN_NEXT_WND:
  415.         // post current stuff, begin attachment in NEXT article
  416.         if (!ReviewAttach)
  417.             CommState = ST_POST_WAIT_END;
  418.  
  419.         GenerateSubject (headerBlock, origSubject, thisPart, numParts);
  420.         saveHeaderBytes = headerBlock->numBytes;
  421.         
  422.         if (GenerateMIME)
  423.         {
  424.                   if (AddEndedLineToTextBlock (headerBlock, "Content-Type: text/plain", aMode))
  425.             {  AttachmentState = ATTACH_DONE; break;  }
  426.         }
  427.         if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  428.             {  AttachmentState = ATTACH_DONE; break;  }
  429.         PostTextBlock (headerBlock);
  430.         PostTextBlock (body);  
  431.         PostTextBlock (tail);  
  432.  
  433.         thisPart = 1;
  434.         currentCoded->sequence = thisPart;    // status window info
  435.         AttachmentState = ATTACH_WAIT;
  436.  
  437.         EndAttach ();
  438.         if (!ReviewAttach)
  439.             return;
  440.  
  441.         break;
  442.  
  443.     case ATTACH_WAIT:
  444.         if (InitiateAttach (NEW_WND, thisDocType))
  445.             {  AttachmentState = ATTACH_DONE; break;  }
  446.         AttachmentState = ATTACH_MAIN;
  447.         if (!ReviewAttach)
  448.             return;
  449.  
  450.         break;
  451.  
  452.     case ATTACH_MAIN:
  453.         if (!ReviewAttach)
  454.             CommState = ST_POST_WAIT_END;
  455.  
  456.         headerBlock->numLines = saveHeaderLines;    // reset to orig header
  457.         headerBlock->numBytes = saveHeaderBytes;
  458.  
  459.         GenerateSubject (headerBlock, origSubject, thisPart, numParts);
  460.         saveHeaderBytes = headerBlock->numBytes;
  461.                 if (GenerateMIME)
  462.                 {
  463.           if (numParts > 1)
  464.           {
  465.             if (AddEndedLineToTextBlock (headerBlock, "Content-Type: message/partial;", aMode))
  466.                 {  AttachmentState = ATTACH_DONE; break;  }
  467.             sprintf (temp, "     id=%s;", attachmentID);
  468.             if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  469.                 {  AttachmentState = ATTACH_DONE; break;  }
  470.             sprintf (temp, "     number=%d; total=%d", thisPart, numParts);
  471.             if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  472.                 {  AttachmentState = ATTACH_DONE; break;  }
  473.  
  474.             if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  475.                 {  AttachmentState = ATTACH_DONE; break;  }
  476.           }
  477.           if (thisPart == 1)
  478.           {
  479.              for (i = 0, found = FALSE; i < NUM_CONTENT_TYPES && !found; i++)
  480.                 if (!_stricmp (ContentType, ContentTypes[i]))
  481.                     found = TRUE;
  482.  
  483.             if (!_stricmp (ContentType, "Other") || !found)
  484.                 sprintf (temp, "Content-Type: Application/octet-stream");
  485.             else                    
  486.                 sprintf (temp, "Content-Type: %s", ContentType);
  487.  
  488.             if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  489.                 {  AttachmentState = ATTACH_DONE; break;  }
  490.                      
  491.             switch (EncodingTypeNum)
  492.             {
  493.             case CODE_UU:    
  494.                 sprintf (temp, "Content-Transfer-Encoding: %s", MIMEUUType);
  495.                 break;
  496.             case CODE_XX:
  497.                 sprintf (temp, "Content-Transfer-Encoding: %s", MIMEXXType);
  498.                 break;
  499.             case CODE_CUSTOM:
  500.                 sprintf (temp, "Content-Transfer-Encoding: %s", MIMECustomType);
  501.                 break;
  502.             case CODE_BASE64:
  503.                 strcpy (temp, "Content-Transfer-Encoding: Base64");
  504.                 break;
  505.             case CODE_NONE:
  506.                 temp[0] = '\0';
  507.             }
  508.             if (temp[0] != '\0' &&
  509.                (AddEndedLineToTextBlock (headerBlock, temp, aMode)))
  510.                 {  AttachmentState = ATTACH_DONE; break;  }
  511.  
  512.             if (AddEndedLineToTextBlock (headerBlock, "",aMode))
  513.                 {  AttachmentState = ATTACH_DONE; break;  }
  514.           }
  515.         }
  516.  
  517.         // if multipart/mixed and first part, then the main header 
  518.         // was already displayed, so we now want to post from the end 
  519.         // of that header on (byteCount already set above)
  520.         if (MultipartMixed && thisPart == 1)
  521.         {
  522.             if (GenerateMIME)
  523.                 PostPartialTextBlock (headerBlock, saveHeaderLines, byteCount-saveHeaderBytes);
  524.         }
  525.         else                                
  526.         {
  527.             PostTextBlock (headerBlock);
  528.             byteCount = headerBlock->numBytes;
  529.         }
  530.  
  531.         if (numParts > 1)
  532.         {
  533.             if (attachLine == attachment->numLines)
  534.             {
  535.                 sprintf (temp, "[WinVn: Humble apologies: the # of attachment blocks was estimated incorrectly]\r");
  536.                 if (aMode == ADD_TO_EDIT) 
  537.                     strcat (temp, "\n");
  538.                 PostOneLine (temp, &dummyLong, 0);
  539.                 thisPart = numParts;
  540.             }
  541.             else
  542.             {
  543.                 // calculate number of bytes from attachment to use 
  544.                 // in this part: we've already used byteCount bytes
  545.                 // in headers, and we need to leave room for the tail
  546.                 byteCount = ArticleSplitLength - byteCount - tail->numBytes;
  547.                 if ((attachLine = PostPartialTextBlock (attachment, attachLine, byteCount)) == 0)
  548.                     {  AttachmentState = ATTACH_DONE; break;  }
  549.             }
  550.         }
  551.         else
  552.             PostTextBlock (attachment);
  553.         
  554.         // if this is the last section, don't end it since we may
  555.         // still have a boundary and a tail to add
  556.         if (thisPart + 1 <= numParts) 
  557.         {
  558.             thisPart++;
  559.             AttachmentState = ATTACH_WAIT;
  560.  
  561.             currentCoded->sequence = thisPart;    // status window info
  562.             currentCoded->numLines = 0;
  563.  
  564.             EndAttach ();
  565.             if (!ReviewAttach)
  566.                 return;
  567.         }
  568.         else // Done with attachment
  569.         {    
  570.             // if multi-part/mixed then need to attach the final boundary
  571.             if (GenerateMIME && MultipartMixed)
  572.             {
  573.                 ResetTextBlock (body);
  574.                 if (AddEndedLineToTextBlock (body, "", aMode))
  575.                     {  AttachmentState = ATTACH_DONE; break;  }
  576.                 sprintf (temp, "--%s--", MIMEBoundary);
  577.                 if (AddEndedLineToTextBlock (body, temp, aMode))
  578.                     {  AttachmentState = ATTACH_DONE; break;  }
  579.                 PostTextBlock (body);
  580.             }    
  581.                 
  582.             // Signature/tail ends up after last boundary, in epilogue
  583.             PostTextBlock (tail);
  584.             AttachmentState = ATTACH_DONE;
  585.             abort = CONTINUE;        // successful
  586.  
  587.             EndAttach ();
  588.             if (!ReviewAttach)
  589.                 return;
  590.         }
  591.         break;
  592.  
  593.     case ATTACH_DONE:
  594.         FinishAttachment (abort); 
  595.         AttachmentState = ATTACH_NONE;
  596.         break;
  597.     
  598.     } // end of switch (AttachmentState)
  599.   
  600.   } // end of while (AttachmentState != ATTACH_NONE)
  601.   return;
  602. }
  603.  
  604. void
  605. FinishAttachment (int action)
  606. {
  607.     char temp[255];
  608.     
  609.     FreeTextBlock (headerBlock);
  610.     FreeTextBlock (body);
  611.     FreeTextBlock (attachment);
  612.     
  613.     CodingState = INACTIVE;
  614.     DestroyStatusArea();
  615.  
  616.     // if we are managing the post (not reviewing), then we must close the
  617.     // one post window when we're through (don't close if aborted)
  618.     if (!ReviewAttach)
  619.     {
  620.         if (action == CONTINUE)
  621.         {
  622.             sprintf (temp, "Posting completed in %d part", numParts);
  623.             if (numParts > 1)
  624.                 strcat (temp, "s");
  625.                 
  626.             MessageBox (thisPostWnd->hWnd, temp, "Posting done", MB_OK|MB_ICONINFORMATION);
  627.             DestroyWindow (thisPostWnd->hWnd);
  628.         }
  629.         GlobalFreePtr (commSpool);
  630.     }        
  631.     ReviewAttach = saveReviewAttach;
  632. }
  633.  
  634. /* ------------------------------------------------------------------------
  635.  *     Reads current text from the posting edit buffer, 
  636.  *    splits all RFC822 header stuff into header block,
  637.  *        save off subject line from header during copy
  638.  *    and body up to any signature into the body block.
  639.  *    from signature on goes into tail block
  640.  *    This is so we can insert our MIME stuff right in between
  641.  *    Assumes there is a null (blank) line between RFC822 header and body
  642.  *    Tailing signature
  643.  */
  644. #define READING_HEADER     1
  645. #define READING_BODY    2
  646. #define READING_TAIL    3
  647. BOOL
  648. SplitCurrentHeader (TypTextBlock *header, TypTextBlock *body, TypTextBlock *tail, char *origSubject)
  649. {
  650.         char *editBuf, *ptr, *end;
  651.         int state;
  652.     char temp[MAXINTERNALLINE];
  653.             
  654.     origSubject[0] = '\0';
  655.     if ((editBuf = GetEditText (hThisEditWnd)) == NULL)
  656.         return (FAIL);
  657.     
  658.     for (state = READING_HEADER, ptr = editBuf; *ptr != '\0';)
  659.     {
  660.         end = strstr (ptr, "\r\n");     // all edit buf lines end in \r\n
  661.         if (end == NULL)
  662.         {
  663.             strcpy (temp, ptr);    // last line - no \r\n
  664.             *ptr = '\0';        // finish loop, then stop
  665.         }
  666.         else
  667.         {
  668.             *end = '\0';            // strip \r\n
  669.             strcpy (temp, ptr);
  670.             ptr = end + 2;          // skip \r\n for next line
  671.         }
  672.         switch (state)
  673.         {
  674.           case READING_HEADER:
  675.             if (!IsBlankStr(temp))
  676.             {
  677.                 if (AddEndedLineToTextBlock (header, temp, aMode))
  678.                     return (FAIL);;
  679.                 if (!_strnicmp (temp, "subject:", 8))
  680.                     strcpy (origSubject, temp);
  681.             }
  682.             else    // switch to reading body                    
  683.             {
  684.                 state = READING_BODY;
  685.                 continue;
  686.             }
  687.             break;
  688.         
  689.           case READING_BODY:
  690.             if (body->numLines == 0 && IsBlankStr (temp))
  691.                 continue;    // skip leading blank lines
  692.                 
  693.             if (EnableSig && Signature->numLines > 0 && 
  694.                 !strcmp (temp, TextBlockLine (Signature, 0)))
  695.             {
  696.                 if (AddEndedLineToTextBlock (tail, temp, aMode))
  697.                     return (FAIL);
  698.                 state = READING_TAIL;
  699.                 continue;
  700.             }
  701.             if (AddEndedLineToTextBlock (body, temp, aMode))
  702.                 return (FAIL);
  703.             break;
  704.         
  705.           case READING_TAIL:
  706.             if (AddEndedLineToTextBlock (tail, temp, aMode))
  707.                 return (FAIL);
  708.             }       
  709.  
  710.     }
  711.     GlobalFreePtr (editBuf);
  712.     return (SUCCESS);
  713. }    
  714.     
  715. /* ------------------------------------------------------------------------
  716.  *    Start/end posting
  717.  */
  718. BOOL
  719. InitiateAttach (int useWnd, int DocType)
  720. {
  721.     WndEdit *NewWndPost;
  722.         
  723.     if (ReviewAttach)
  724.     {
  725.         /* create new window for each posted section
  726.          * if attach-now or thisPart==0 use existing window for 1st section
  727.          */
  728.         if (useWnd == NEW_WND)
  729.         {
  730.             if ((hParentWnd = CreatePostingWnd (hParentWnd, NULL, DocType)) == NULL)
  731.             {
  732.                 MessageBox (hParentWnd, "Failed to create new attachment window", "Posting Window Creation", MB_OK);
  733.                 return (FAIL);
  734.             }
  735.                             
  736.             if (DocType == DOCTYPE_POSTING)
  737.                NewWndPost = getWndEdit(WndPosts, hParentWnd, MAXPOSTWNDS);
  738.             else
  739.                NewWndPost = getWndEdit(WndMails, hParentWnd, MAXMAILWNDS);
  740.             
  741.             NewWndPost->dirty = DT_DIRTY;
  742.             hThisEditWnd = NewWndPost->hWndEdit;
  743.         }
  744.         sprintf (str, "Review Attachment Part %d of %d", thisPart, numParts);
  745.         SetWindowText (hParentWnd, str);
  746.         if ((editMem = (char *) GlobalAllocPtr (GMEM_MOVEABLE|GMEM_ZEROINIT, EDIT_SIZE_INC*sizeof(char))) == NULL)
  747.         {
  748.             MessageBox (hParentWnd, "Memory allocation failure", "Attachment", MB_OK);
  749.             return (FAIL);
  750.         }
  751.         editMaxSize = EDIT_SIZE_INC;
  752.         editSize = 0;
  753.     }
  754.     else        
  755.         if (!StartPost (thisPostWnd))
  756.             return (FAIL);
  757.  
  758.     return (SUCCESS);
  759. }
  760.  
  761. void
  762. EndAttach (HWND hParentWnd)
  763. {
  764.     unsigned long dummyLong;
  765.     
  766.     if (ReviewAttach)
  767.     {
  768.         SetEditText (hThisEditWnd, editMem);
  769.         GlobalFreePtr (editMem);
  770.     }
  771.     else
  772.     {
  773.         PostOneLine (".\r\n", &dummyLong, 0);
  774.         FlushCommSpool ();
  775.     }
  776. }
  777.  
  778. void
  779. FlushCommSpool ()
  780. {
  781.     if (commSpoolLen > 0)
  782.     {
  783.         PutCommData (commSpool, commSpoolLen);
  784.         commSpoolLen = 0;
  785.         commSpool[0] = '\0';
  786.     }
  787. }
  788.  
  789. /* ------------------------------------------------------------------------
  790.  * Post the contents of a text block
  791.  *    Assumes posting already initiated, and does not end the posting
  792.  *    Lines must end in \r\n
  793.  */
  794.  
  795. int 
  796. PostOneLine (char *str, unsigned long *byteCount, unsigned long maxBytes)
  797. {
  798.     unsigned int len;
  799.  
  800.     len = strlen (str);
  801.         
  802.     *byteCount += (long)len;
  803.     if (maxBytes > 0 && *byteCount >= maxBytes)
  804.         return (SUCCESS);
  805.  
  806.     if (ReviewAttach)
  807.     {
  808.         editSize += len;
  809.         if (editSize >= editMaxSize)
  810.         {
  811.             editMaxSize += max(EDIT_SIZE_INC, len);
  812.             if ((editMem = GlobalReAllocPtr (editMem, editMaxSize*sizeof(char), GMEM_MOVEABLE)) == NULL)
  813.             {
  814.                 MessageBox (hThisEditWnd, "Memory allocation failure", "Build Attachment", MB_OK);
  815.                 return (FAIL);
  816.             }
  817.         }
  818.         strcat (editMem, str);
  819.         currentCoded->numBytes = (long)editSize;
  820.     }
  821.     else
  822.     {
  823.         if (commSpoolLen + len >= MAX_COMM_SPOOL)
  824.             FlushCommSpool ();
  825.  
  826.         strcat (commSpool, str);
  827.         commSpoolLen += len;
  828.         currentCoded->numBytes += len;
  829.     }
  830.  
  831.     return (SUCCESS);
  832. }
  833.  
  834. void
  835. PostTextBlock (TypTextBlock *block)
  836. {
  837.     PostPartialTextBlock (block, 0L, 0L);
  838. }
  839.  
  840. unsigned long
  841. PostPartialTextBlock (TypTextBlock *block, unsigned long start, unsigned long maxBytes)
  842. {
  843.     register unsigned long i;
  844.     unsigned long byteCount;
  845.  
  846.     byteCount = 0;    
  847.             
  848.     for (i = start; i < block->numLines; i++)
  849.     {
  850.         if (PostOneLine (TextBlockLine (block, i), &byteCount, maxBytes) == FAIL)
  851.             return (0);
  852.         
  853.         if (maxBytes > 0 && byteCount >= maxBytes)
  854.             break;
  855.             
  856.         currentCoded->numLines++;
  857.         if (currentCoded->numLines % STATUS_UPDATE_FREQ == 0)
  858.             UpdateBlockStatus();
  859.     }
  860.     UpdateBlockStatus();    // show final size
  861.     return (i);
  862. }
  863. /* ------------------------------------------------------------------------
  864.  *    Add a line to the given header block which contains the MIME-Version
  865.  */
  866. BOOL
  867. AddMIMEVersion (TypTextBlock *header)
  868. {
  869.     char temp[MAXINTERNALLINE];
  870.     
  871.     sprintf (temp, "MIME-Version: %s", MIME_VERSION);
  872.     if (AddEndedLineToTextBlock (header, temp, aMode))
  873.         return (FAIL);;
  874.  
  875.     return (SUCCESS);
  876. }
  877.  
  878. /* ------------------------------------------------------------------------
  879.  *    Generate a subject line based on orig subject line, and the
  880.  *     subject template
  881.  *        Replace %f with AttachFileName
  882.  *        Replace %p with part #
  883.  *        Replace %0p with part # 0 padded to length of total # parts
  884.  *        Replace %t with total # parts
  885.  *        Replace %s with orig subject content
  886.  *
  887.  */
  888. void
  889. GenerateSubject (TypTextBlock *header, char *origSubject, 
  890.          unsigned int part, unsigned int numParts)
  891. {
  892.     register char *src, *dest, *ptr;
  893.     register unsigned long num;
  894.     char newSubject[MAXINTERNALLINE];
  895.     char endLine[3], numStr[10];
  896.     int numZeros;
  897.     extern char *NameWithoutPath ();
  898.  
  899.     for (num = 0; num < header->numLines; num++)
  900.         if (!_strnicmp (TextBlockLine (header, num), "subject:", 8))
  901.             break;
  902.         
  903.     ptr = strpbrk (TextBlockLine (header, num), "\n\r");
  904.     strcpy (endLine, ptr);
  905.  
  906.     for (src = SubjectTemplate, dest = newSubject; *src != NULL;)
  907.     {
  908.         if (*src == '%')
  909.         {
  910.             src++;
  911.             switch (*src)
  912.             {
  913.             case '%':        // literal percent is %%
  914.                 *dest++ = '%';
  915.                 break;
  916.             case 's':
  917.                 for (ptr = origSubject; *ptr; *dest++ = *ptr++);
  918.                 break;
  919.             case 'f':
  920.                 NameWithoutPath (str, AttachFileName);                
  921.                 for (ptr = str; *ptr; *dest++ = *ptr++);
  922.                 break;
  923.  
  924.             case '0':
  925.                 if (*(src+1) == 'p')
  926.                 {
  927.                     src++;    // skip zero
  928.                     // zero-pad number to length of numParts string
  929.                     itoa (numParts, numStr, 10);    // longer or equal in length to part
  930.                     itoa (part, str, 10);
  931.                     
  932.                     for (numZeros = strlen(numStr) - strlen(str); numZeros; numZeros--)
  933.                         *dest++ = '0';
  934.                     
  935.                     for (ptr = str; *ptr; *dest++ = *ptr++);
  936.                 }
  937.                 break;
  938.                 
  939.             case 'p':
  940.                 itoa (part, numStr, 10);
  941.                 for (ptr = numStr; *ptr; *dest++ = *ptr++);
  942.                 break;
  943.  
  944.             case 't':
  945.                 itoa (numParts, numStr, 10);
  946.                 for (ptr = numStr; *ptr; *dest++ = *ptr++);
  947.                 break;
  948.  
  949.             default:
  950.                 *dest++ = '%';
  951.                 *dest++ = *src;
  952.                 break;
  953.  
  954.             }
  955.             src++;    // skip control char after %
  956.             continue;
  957.         }
  958.         *dest++ = *src++;    
  959.     }
  960.     *dest = '\0';   
  961.     strcat (dest, endLine);    // replace end of line
  962.  
  963.     ReplaceLineInTextBlock (header, num, newSubject);
  964. }
  965.  
  966.  
  967. #if OLD_PLAIN_FILE
  968. /* ------------------------------------------------------------------------
  969.  *     Directly modifies the Edit buffer of the parent multi-line edit wnd
  970.  *    Appends contents of fileName to buffer
  971.  */
  972. void
  973. AppendPlainFileToPost (char *fileName)
  974. {
  975.     HFILE hFile;
  976.     register unsigned int i;
  977.         char *editBuf, *inBuf;
  978.         unsigned int endPtr, size, numRead;
  979.         
  980.         inBuf = (char *) GlobalAllocPtr(GMEM_FIXED, 2048*sizeof(char));
  981.     editBuf = GetEditText (hThisEditWnd);
  982.     
  983.     size = strlen (editBuf);        
  984.     if ((hFile = _lopen (fileName, READ)) == HFILE_ERROR)
  985.     {
  986.         sprintf(str, "Could not open file %s for read", fileName);
  987.         MessageBox (hParentWnd, str, "Attachment Open File Error", MB_OK);
  988.         return;
  989.     }
  990.     
  991.         while (1)
  992.         {
  993.            if ((numRead = _lread(hFile, inBuf, 2048)) == 0)
  994.                 break;
  995.                for (i = 0; i < numRead; i++)
  996.           if (!__isascii (inBuf[i]))
  997.           {
  998.             sprintf(str, "File %s appears to contain non-ASCII data.\nBinary files must be encoded for attachment", fileName);
  999.             MessageBox (hParentWnd, str, "Non-ASCII File Error", MB_OK);
  1000.             goto endAppend;
  1001.           }
  1002.         
  1003.         endPtr = size;
  1004.         size += numRead;
  1005.         editBuf = GlobalReAllocPtr (editBuf, size, GMEM_MOVEABLE);
  1006.         memmove (editBuf + endPtr, inBuf, numRead);
  1007.     }
  1008.    
  1009.    endAppend:;
  1010.     _lclose(hFile);
  1011.  
  1012.     SetEditText (hThisEditWnd, editBuf);
  1013.         GlobalFreePtr (editBuf);
  1014.         GlobalFreePtr (inBuf);
  1015. }
  1016. #endif                                                                       
  1017.  
  1018. #if OLD_HEADER
  1019. /* ------------------------------------------------------------------------
  1020.  * Returns true for lines which look like standard header lines
  1021.  * Returns non-zero if should skip this line, else zero
  1022.  * A binary search through a list of words would be really smart
  1023.  * Lazy approach
  1024.  */
  1025. int
  1026. TestRfc822HeaderLine (char *line)
  1027. {
  1028.     switch (tolower(line[0]))
  1029.     {
  1030.     case 'd': 
  1031.         return (!_strnicmp(line, "date", 4));
  1032.     case 'f': 
  1033.         return (!_strnicmp(line, "follow", 6) ||
  1034.               !_strnicmp(line, "from", 4));
  1035.      case 'k':
  1036.         return (!_strnicmp(line, "keywords", 8));
  1037.         
  1038.     case 'l':
  1039.         return (!_strnicmp(line, "lines", 5));
  1040.     case 'm':
  1041.         return (!_strnicmp(line, "message", 7));
  1042.     case 'n':
  1043.         return (!_strnicmp(line, "newsgrou", 8) ||
  1044.               !_strnicmp(line, "nntp", 4));
  1045.     case 'o':
  1046.         return (!_strnicmp(line, "organiza", 8) ||
  1047.              !_strnicmp(line, "originat", 8));
  1048.         case 'p':
  1049.         return (!_strnicmp(line, "path", 4));
  1050.     case 'r':
  1051.         return (!_strnicmp(line, "referenc", 8) ||
  1052.             !_strnicmp(line, "reply", 5));
  1053.     case 's':
  1054.          return (!_strnicmp(line, "sender", 6) ||
  1055.              !_strnicmp(line, "subject:", 8) ||
  1056.              !_strnicmp(line, "summary", 7));
  1057.     case 'x':
  1058.         return (!_strnicmp(line, "xref:", 5) ||
  1059.                 !_strnicmp(line, "x-news", 6));
  1060.     default:
  1061.         return (0);
  1062.     }
  1063. }    
  1064.  
  1065. #endif                                                                       
  1066. @
  1067.  
  1068.  
  1069. 1.8
  1070. log
  1071. @misc encoding/decoding changes
  1072. @
  1073. text
  1074. @d14 1
  1075. a14 1
  1076.  * $Id: wvattach.c 1.7 1994/08/11 00:09:17 jcooper Exp $
  1077. d16 3
  1078. d40 3
  1079. a45 2
  1080. #include "wvglob.h"
  1081. #include "winvn.h"
  1082. a163 1
  1083.     Attaching = TRUE;
  1084. d251 1
  1085. a251 1
  1086. ProcessAttach (int cancel)
  1087. d259 1
  1088. a259 1
  1089.     if (cancel) 
  1090. d541 1
  1091. a541 1
  1092. FinishAttachment (int abort)
  1093. a547 1
  1094.     Attaching = FALSE;
  1095. d556 1
  1096. a556 1
  1097.         if (abort == CONTINUE)
  1098. d819 1
  1099. d830 3
  1100. a832 2
  1101.     char numStr[MAXINTERNALLINE], newSubject[MAXINTERNALLINE];
  1102.     char endLine[3];
  1103. d859 16
  1104. d879 1
  1105. d884 1
  1106. @
  1107.  
  1108.  
  1109. 1.7
  1110. log
  1111. @Enhancements to Mime and article encoding/encoding
  1112. @
  1113. text
  1114. @d14 1
  1115. a14 1
  1116.  * $Id: wvattach.c 1.6 1994/06/09 18:51:30 rushing Exp $
  1117. d16 3
  1118. d737 3
  1119. a741 3
  1120.         if (maxBytes > 0 && *byteCount >= maxBytes)
  1121.             return (SUCCESS);
  1122.  
  1123. @
  1124.  
  1125.  
  1126. 1.6
  1127. log
  1128. @problem with symbol 'header' on AXP/NT
  1129. @
  1130. text
  1131. @d6 1
  1132. a6 1
  1133.  *              mail or posting                                     *
  1134. d10 1
  1135. a10 1
  1136.  * Author: John S. Cooper (jcoop@@apl.com)                           *
  1137. d14 1
  1138. a14 1
  1139.  * $Id: wvattach.c 1.5 1994/05/23 18:37:00 jcooper Exp $
  1140. d16 3
  1141. d140 1
  1142. a140 1
  1143.     unsigned long offset;
  1144. d181 1
  1145. a181 1
  1146.             {  FinishAttachment (TRUE); return;  }
  1147. d184 1
  1148. a184 1
  1149.         {  FinishAttachment (TRUE); return;  }
  1150. d193 1
  1151. a193 1
  1152.         {  FinishAttachment (TRUE); return;  }
  1153. d195 1
  1154. a195 1
  1155.     if (BlankBeforeMIME)
  1156. d197 1
  1157. a197 1
  1158.         {  FinishAttachment (TRUE); return;  }
  1159. d199 2
  1160. a200 2
  1161.         if (AddMIMEVersion (headerBlock))
  1162.             {  FinishAttachment (TRUE); return;  }
  1163. d206 1
  1164. a206 1
  1165.         FinishAttachment (TRUE); return;
  1166. d215 2
  1167. a216 1
  1168.     }        
  1169. d226 1
  1170. d228 1
  1171. a228 1
  1172.              (long)numParts*(headerBlock->numBytes + tail->numBytes + 200) + 
  1173. d234 1
  1174. a234 1
  1175.     ProcessAttach (0);
  1176. d259 1
  1177. a259 1
  1178.  while (AttachmentState != ATTACH_NONE) {
  1179. d263 1
  1180. a263 1
  1181.         abort = TRUE;
  1182. d300 3
  1183. a302 1
  1184.           if (AddEndedLineToTextBlock (headerBlock, "Content-Type: multipart/mixed;",aMode))
  1185. d305 2
  1186. a306 2
  1187.           sprintf (temp, "     Boundary=\"%s\"", MIMEBoundary);
  1188.           if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  1189. d309 3
  1190. a311 3
  1191.           // blank preamble here
  1192.           // each boundary must be preceded by a CRLF (add "")
  1193.           if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  1194. d313 2
  1195. a314 2
  1196.           sprintf (temp, "--%s", MIMEBoundary);
  1197.           if (AddEndedLineToTextBlock (headerBlock, temp, aMode))
  1198. d317 2
  1199. a318 2
  1200.                   // explicitly type the encapsulated section
  1201.           if (AddEndedLineToTextBlock (headerBlock, "Content-Type: text/plain", aMode))
  1202. d320 1
  1203. a320 1
  1204.           if (AddEndedLineToTextBlock (headerBlock, "", aMode))
  1205. d323 1
  1206. a323 1
  1207.           if (AddEndedLineToTextBlock (body, "", aMode))
  1208. d325 2
  1209. a326 2
  1210.           sprintf (temp, "--%s", MIMEBoundary);
  1211.           if (AddEndedLineToTextBlock (body, temp, aMode))
  1212. d328 8
  1213. d338 1
  1214. a339 1
  1215.           MultipartMixed = TRUE;
  1216. d351 4
  1217. a354 1
  1218.         if (AddEndedLineToTextBlock (headerBlock, "Content-Type: text/plain", aMode))
  1219. d356 1
  1220. d391 4
  1221. a394 3
  1222.  
  1223.         if (numParts > 1)
  1224.         {
  1225. d406 4
  1226. a409 4
  1227.         }
  1228.         if (thisPart == 1)
  1229.         {
  1230.             for (i = 0, found = FALSE; i < NUM_CONTENT_TYPES && !found; i++)
  1231. d414 1
  1232. a414 1
  1233.                 sprintf (temp, "Content-Type: X-%s", ContentType);                
  1234. d420 1
  1235. a420 1
  1236.             
  1237. d424 1
  1238. a424 1
  1239.                 strcpy (temp, "Content-Transfer-Encoding: X-uue");
  1240. d427 1
  1241. a427 1
  1242.                 strcpy (temp, "Content-Transfer-Encoding: X-xxe");
  1243. d430 1
  1244. a430 1
  1245.                 strcpy (temp, "Content-Transfer-Encoding: X-User-Defined");
  1246. d441 1
  1247. d444 1
  1248. d451 2
  1249. d454 1
  1250. d465 1
  1251. a465 1
  1252.                 sprintf (temp, "Most humble apologies: the # of attachment blocks was estimated incorrectly\r");
  1253. d480 2
  1254. a481 1
  1255.         } else
  1256. d501 1
  1257. a501 1
  1258.             if (MultipartMixed)
  1259. d515 1
  1260. a515 1
  1261.             abort = FALSE;        // successful
  1262. d527 5
  1263. a531 3
  1264.     }
  1265.  }
  1266.  return;
  1267. d551 1
  1268. a551 1
  1269.         if (!abort)
  1270. @
  1271.  
  1272.  
  1273. 1.5
  1274. log
  1275. @new attach code, session [dis]connect
  1276. @
  1277. text
  1278. @d14 1
  1279. a14 1
  1280.  * $Id: wvattach.c 1.3 1994/02/24 21:27:10 jcoop Exp $
  1281. d16 3
  1282. d86 1
  1283. a86 1
  1284. TypTextBlock *header, *body, *attachment, *tail;
  1285. d145 1
  1286. a145 1
  1287.     if ((header     = InitTextBlock (hCodedBlockWnd)) == NULL)
  1288. d189 1
  1289. a189 1
  1290.     if (SplitCurrentHeader (header, body, tail, origSubject))
  1291. d193 1
  1292. a193 1
  1293.        if (AddEndedLineToTextBlock (header, "", aMode))
  1294. d196 1
  1295. a196 1
  1296.         if (AddMIMEVersion (header))
  1297. d200 1
  1298. a200 1
  1299.     if (header->numBytes + tail->numBytes + 200 > ArticleSplitLength)
  1300. d208 1
  1301. a208 1
  1302.        (body->numBytes + header->numBytes + tail->numBytes + 200 > ArticleSplitLength))
  1303. d223 1
  1304. a223 1
  1305.              (long)numParts*(header->numBytes + tail->numBytes + 200) + 
  1306. d262 2
  1307. a263 2
  1308.         saveHeaderLines = header->numLines;
  1309.         saveHeaderBytes = header->numBytes;
  1310. d292 2
  1311. a293 2
  1312.           GenerateSubject (header, origSubject, thisPart, numParts);
  1313.           saveHeaderBytes = header->numBytes;
  1314. d295 1
  1315. a295 1
  1316.           if (AddEndedLineToTextBlock (header, "Content-Type: multipart/mixed;",aMode))
  1317. d299 1
  1318. a299 1
  1319.           if (AddEndedLineToTextBlock (header, temp, aMode))
  1320. d304 1
  1321. a304 1
  1322.           if (AddEndedLineToTextBlock (header, "", aMode))
  1323. d307 1
  1324. a307 1
  1325.           if (AddEndedLineToTextBlock (header, temp, aMode))
  1326. d311 1
  1327. a311 1
  1328.           if (AddEndedLineToTextBlock (header, "Content-Type: text/plain", aMode))
  1329. d313 1
  1330. a313 1
  1331.           if (AddEndedLineToTextBlock (header, "", aMode))
  1332. d321 1
  1333. a321 1
  1334.           PostTextBlock (header);
  1335. d323 1
  1336. a323 1
  1337.           byteCount = header->numBytes + body->numBytes;
  1338. d334 3
  1339. a336 3
  1340.         GenerateSubject (header, origSubject, thisPart, numParts);
  1341.         saveHeaderBytes = header->numBytes;
  1342.         if (AddEndedLineToTextBlock (header, "Content-Type: text/plain", aMode))
  1343. d338 1
  1344. a338 1
  1345.         if (AddEndedLineToTextBlock (header, "", aMode))
  1346. d340 1
  1347. a340 1
  1348.         PostTextBlock (header);
  1349. d367 2
  1350. a368 2
  1351.         header->numLines = saveHeaderLines;    // reset to orig header
  1352.         header->numBytes = saveHeaderBytes;
  1353. d370 2
  1354. a371 2
  1355.         GenerateSubject (header, origSubject, thisPart, numParts);
  1356.         saveHeaderBytes = header->numBytes;
  1357. d375 1
  1358. a375 1
  1359.             if (AddEndedLineToTextBlock (header, "Content-Type: message/partial;", aMode))
  1360. d378 1
  1361. a378 1
  1362.             if (AddEndedLineToTextBlock (header, temp, aMode))
  1363. d381 1
  1364. a381 1
  1365.             if (AddEndedLineToTextBlock (header, temp, aMode))
  1366. d384 1
  1367. a384 1
  1368.             if (AddEndedLineToTextBlock (header, "", aMode))
  1369. d398 1
  1370. a398 1
  1371.             if (AddEndedLineToTextBlock (header, temp, aMode))
  1372. d419 1
  1373. a419 1
  1374.                (AddEndedLineToTextBlock (header, temp, aMode)))
  1375. d421 1
  1376. a421 1
  1377.             if (AddEndedLineToTextBlock (header, "",aMode))
  1378. d429 1
  1379. a429 1
  1380.                 PostPartialTextBlock (header, saveHeaderLines, byteCount-saveHeaderBytes);
  1381. d432 2
  1382. a433 2
  1383.             PostTextBlock (header);
  1384.             byteCount = header->numBytes;
  1385. d511 1
  1386. a511 1
  1387.     FreeTextBlock (header);
  1388. d948 1
  1389. a948 1
  1390. #endif                                                                       @
  1391.  
  1392.  
  1393. 1.4
  1394. log
  1395. @changes for gensock & version 0.91
  1396. @
  1397. text
  1398. @d14 1
  1399. a14 1
  1400.  * $Id: wvattach.c 1.3 1994/02/24 21:27:10 jcoop Exp rushing $
  1401. d45 1
  1402. d48 1
  1403. d53 2
  1404. d56 13
  1405. d73 8
  1406. d83 7
  1407. d93 27
  1408. a119 3
  1409. int aMode;            // attachment mode for ended line chars
  1410. unsigned int thisPart, numParts;
  1411. TypTextBlock *thisPostText;
  1412. d122 1
  1413. a122 1
  1414.  *     hParentWnd is handle to multi-line edit posting window
  1415. a132 3
  1416.     register unsigned long byteCount;
  1417.         TypTextBlock *header, *body, *attachment, *tail;
  1418.         char attachmentID[MAXINTERNALLINE], origSubject[MAXINTERNALLINE];    
  1419. d134 1
  1420. a134 3
  1421.     unsigned long line, saveHeaderLines, saveHeaderBytes, offset;
  1422.     char temp[MAXINTERNALLINE];
  1423.     BOOL MultipartMixed;
  1424. d139 2
  1425. a140 8
  1426.  
  1427.     Attaching = TRUE;
  1428.     MultipartMixed = FALSE;
  1429.     if (ReviewAttach)
  1430.         aMode = ADD_TO_EDIT;
  1431.     else
  1432.         aMode = ADD_TO_POST;
  1433.     
  1434. d151 18
  1435. d170 1
  1436. a170 1
  1437.         strcpy (currentCoded->ident, fileName);    // status info
  1438. d172 1
  1439. a172 1
  1440.     if (EncodingType == CODE_NONE)
  1441. d175 1
  1442. a175 1
  1443.             goto endAttach;
  1444. d177 2
  1445. a178 1
  1446.     else     Encode (attachment, fileName, aMode);
  1447. a185 2
  1448.     byteCount = 0;
  1449.  
  1450. d187 1
  1451. a187 1
  1452.         goto endAttach;
  1453. d191 1
  1454. a191 1
  1455.         goto endAttach;
  1456. d194 1
  1457. a194 2
  1458.             goto endAttach;
  1459.  
  1460. d200 1
  1461. a200 1
  1462.         goto endAttach;
  1463. d204 1
  1464. a204 1
  1465.     if (WhenToAttach == IDD_ATTACH_NOW && 
  1466. d208 1
  1467. a208 1
  1468.         WhenToAttach == IDD_ATTACH_NEXT;
  1469. a209 2
  1470.     saveHeaderLines = header->numLines;
  1471.     saveHeaderBytes = header->numBytes;
  1472. d212 1
  1473. a212 1
  1474.         offset = (WhenToAttach == IDD_ATTACH_NOW) ? body->numBytes : 0;
  1475. d225 21
  1476. a245 1
  1477.     if (WhenToAttach == IDD_ATTACH_NOW)
  1478. d247 13
  1479. a259 4
  1480.         thisPart = 1;
  1481.         if (InitiateAttach (CURRENT_WND, DocType))
  1482.             goto endAttach;
  1483.           GenerateSubject (header, origSubject, thisPart, numParts);
  1484. d261 26
  1485. d289 3
  1486. d293 1
  1487. a293 1
  1488.               goto endAttach;
  1489. d297 1
  1490. a297 1
  1491.             goto endAttach;
  1492. d302 1
  1493. a302 1
  1494.             goto endAttach;
  1495. d305 1
  1496. a305 1
  1497.             goto endAttach;
  1498. d309 1
  1499. a309 1
  1500.             goto endAttach;
  1501. d311 1
  1502. a311 1
  1503.             goto endAttach;
  1504. d314 1
  1505. a314 1
  1506.             goto endAttach;
  1507. d317 1
  1508. a317 1
  1509.             goto endAttach;
  1510. d323 8
  1511. a330 8
  1512.     }
  1513.     else
  1514.     {    // post current stuff, begin attachment in NEXT article
  1515.         if (body->numLines == 0)    // if have body, then mixed
  1516.             ;// Mention to the user that there's no body...
  1517.         thisPart = 0;
  1518.         if (InitiateAttach (CURRENT_WND, DocType))
  1519.         goto endAttach;
  1520. d332 1
  1521. d334 1
  1522. a334 1
  1523.             goto endAttach;
  1524. d336 1
  1525. a336 1
  1526.             goto endAttach;
  1527. d340 5
  1528. d346 20
  1529. a366 3
  1530.         thisPart = 1;
  1531.         if (InitiateAttach (NEW_WND, DocType))
  1532.             goto endAttach;
  1533. a368 12
  1534.     }
  1535.     for (line = 0; thisPart <= numParts; thisPart++)
  1536.     {        
  1537.         if (line == attachment->numLines)
  1538.         {
  1539.             MessageBox (hCodedBlockWnd, "Ok, Ok, I calculated the number of parts wrong. Sorry.", "So Kill Me", MB_OK);
  1540.             break;
  1541.         }
  1542.         header->numLines = saveHeaderLines;    // reset to orig header
  1543.         header->numBytes = saveHeaderBytes;
  1544. //        for (i = saveHeaderLines; i < header->numLines; i++)
  1545. //            GlobalFreePtr (header->text[i]);
  1546. a369 7
  1547.         if (thisPart > 1)            // 1st handled above
  1548.         {
  1549.             if (InitiateAttach (NEW_WND, DocType))
  1550.                 goto endAttach;
  1551.             GenerateSubject (header, origSubject, thisPart, numParts);
  1552.             saveHeaderBytes = header->numBytes;
  1553.         }
  1554. d373 1
  1555. a373 1
  1556.                 goto endAttach;
  1557. d376 1
  1558. a376 1
  1559.                 goto endAttach;
  1560. d379 1
  1561. a379 1
  1562.                 goto endAttach;
  1563. d382 1
  1564. a382 1
  1565.                 goto endAttach;
  1566. d386 6
  1567. a391 2
  1568.             if (!_stricmp (ContentType, "Other"))
  1569.                 strcpy (temp, "Content-Type: X-Other");
  1570. d394 1
  1571. d396 1
  1572. a396 1
  1573.                 goto endAttach;
  1574. d398 1
  1575. a398 1
  1576.             switch (EncodingType)
  1577. d417 1
  1578. a417 1
  1579.                 goto endAttach;
  1580. d419 1
  1581. a419 1
  1582.                 goto endAttach;
  1583. d426 1
  1584. a426 1
  1585.             PostPartialTextBlock (header, saveHeaderLines, byteCount-saveHeaderBytes);
  1586. d435 17
  1587. a451 6
  1588.             // calculate number of bytes from attachment to use 
  1589.             // in this part: we've already used byteCount bytes
  1590.             // in headers, and we need to leave room for the tail
  1591.             byteCount = ArticleSplitLength - byteCount - tail->numBytes;
  1592.             if ((line = PostPartialTextBlock (attachment, line, byteCount)) == 0)
  1593.                 goto endAttach;
  1594. a454 3
  1595.         currentCoded->sequence++;    // status window info
  1596.         currentCoded->numLines = 0;
  1597.         
  1598. d457 31
  1599. a487 1
  1600.         if (thisPart + 1 <= numParts)
  1601. d489 9
  1602. d499 3
  1603. a501 15
  1604.     // if multi-part/mixed then need to attach the final boundary
  1605.     if (MultipartMixed)
  1606.     {
  1607.         ResetTextBlock (body);
  1608.         if (AddEndedLineToTextBlock (body, "", aMode))
  1609.             goto endAttach;
  1610.         sprintf (temp, "--%s--", MIMEBoundary);
  1611.         if (AddEndedLineToTextBlock (body, temp, aMode))
  1612.             goto endAttach;
  1613.         PostTextBlock (body);
  1614.     }    
  1615.         
  1616.     // Signature/tail ends up after last boundary, in epilogue
  1617.     PostTextBlock (tail);
  1618.     EndAttach ();
  1619. d503 5
  1620. a507 1
  1621.    endAttach:;    
  1622. d515 17
  1623. d533 1
  1624. d622 1
  1625. a622 1
  1626.     
  1627. a653 1
  1628. /*
  1629. d655 1
  1630. a655 1
  1631.         if (!StartPost(WndPost))    //!!!! FIX THIS!
  1632. d657 1
  1633. a657 1
  1634. */
  1635. d660 1
  1636. d664 2
  1637. d672 15
  1638. a686 1
  1639.         PutCommLine (".");
  1640. d688 1
  1641. d690 1
  1642. a690 1
  1643.  *      Post the contents of a text block
  1644. d692 1
  1645. a692 2
  1646.  *    Lines in an edit buffer must end in \r\n
  1647.  *    Posted lines have no end chars (PutCommLine adds a \n)
  1648. d694 40
  1649. a743 1
  1650.     register unsigned int len;
  1651. d750 2
  1652. a751 1
  1653.         len = strlen (TextBlockLine (block, i));
  1654. d753 3
  1655. a755 22
  1656.         if (ReviewAttach)
  1657.         {
  1658.             byteCount += (long)len;
  1659.             if (maxBytes > 0 && byteCount >= maxBytes)
  1660.                 break;
  1661.  
  1662.             editSize += len;
  1663.             if (editSize >= editMaxSize)
  1664.             {
  1665.                 editMaxSize += max(EDIT_SIZE_INC, len);
  1666.                 if ((editMem = GlobalReAllocPtr (editMem, editMaxSize*sizeof(char), GMEM_MOVEABLE)) == NULL)
  1667.                 {
  1668.                     MessageBox (hThisEditWnd, "Memory allocation failure", "Build Attachment", MB_OK);
  1669.                     return 0;
  1670.                 }
  1671.             }
  1672.             strcat (editMem, TextBlockLine (block, i));
  1673.             len = strlen (editMem);
  1674.         }
  1675.         else
  1676.             PutCommLine (TextBlockLine (block, i));
  1677.                 
  1678. a756 1
  1679.         currentCoded->numBytes = (long)editSize;
  1680. d943 1
  1681. a943 3
  1682. }
  1683.  
  1684. #endif
  1685. d945 1
  1686. @
  1687.  
  1688.  
  1689. 1.3
  1690. log
  1691. @jcoop changes
  1692. @
  1693. text
  1694. @d14 1
  1695. a14 1
  1696.  * $Id: wvattach.c 1.2 1994/01/22 01:30:03 jcoop Exp $
  1697. d16 3
  1698. d487 1
  1699. a487 1
  1700.         PutCommLine (".\r", 2);
  1701. d534 1
  1702. a534 1
  1703.             PutCommLine (TextBlockLine (block, i), len);
  1704. d724 3
  1705. a726 1
  1706. }    
  1707. a727 1
  1708. #endif                                                                       @
  1709.  
  1710.  
  1711. 1.2
  1712. log
  1713. @90.2 changes
  1714. @
  1715. text
  1716. @d14 1
  1717. a14 1
  1718.  * $Id: wvattach.c 1.1 1994/01/16 12:10:08 jcoop Exp $
  1719. d16 3
  1720. d106 1
  1721. a106 1
  1722.     if (EncodingType == ENCODE_NONE)
  1723. d271 1
  1724. a271 1
  1725.             case ENCODE_UU:    
  1726. d274 1
  1727. a274 1
  1728.             case ENCODE_XX:
  1729. d277 1
  1730. a277 1
  1731.             case ENCODE_CUSTOM:
  1732. d280 1
  1733. a280 1
  1734.             case ENCODE_BASE64:
  1735. d283 1
  1736. a283 1
  1737.             case ENCODE_NONE:
  1738. a477 1
  1739. LRESULT x;
  1740. d480 1
  1741. a480 1
  1742.         x=SetEditText (hThisEditWnd, editMem);
  1743. @
  1744.  
  1745.  
  1746. 1.1
  1747. log
  1748. @Initial revision
  1749. @
  1750. text
  1751. @d14 5
  1752. a18 2
  1753.  * $Id: $
  1754.  * $Log: $
  1755. d465 1
  1756. d467 1
  1757. a467 1
  1758.         if (!StartPost(hParentWnd))        // !!!! FIX THIS!
  1759. d469 1
  1760. a469 1
  1761.  
  1762. @
  1763.